/*=========================================================================

Program:   Virtual Surgery
Language:  C++
Date:      2009-9-1
Version:   0.1
Mail:		   nelfylee@gmail.com

Copyright (c) 2009 Nelfy Lee. All rights reserved.

=========================================================================*/
#include "DisplayFramework.h"
#include "View2D.h"
#include "View3D.h"
#include "Source.h"
#include "PipelineModel.h"


#include <QHBoxLayout>
#include <QSplitter>
#include <QDebug>


DisplayFramework::DisplayFramework(QWidget *parent) 
: QFrame(parent)
{
	m_isViewMaximized=false;
	m_baseSource=NULL;
	m_realTimeSlicingView=NULL;

	m_2dViewLeft = new View2D("2D Left", 1);
	m_2dViewRight = new View2D("2D Right", 2);
	m_3dViewLeft = new View3D("3D Left", 3);
	m_3dViewRight = new View3D("3D Right", 4);
	m_2dViewLeft->setActivated(true);
	m_3dViewLeft->setActivated(true);

	m_2dViewRight->setCrossLineEnabled(false);

	m_splitter2DViews = new QSplitter(this);
	m_splitter3DViews = new QSplitter(this);
	m_splitterVertical = new QSplitter(this);

	m_splitter2DViews->addWidget(m_2dViewLeft);
	m_splitter2DViews->addWidget(m_2dViewRight);
	m_splitter3DViews->addWidget(m_3dViewLeft);
	m_splitter3DViews->addWidget(m_3dViewRight);

	m_splitterVertical->setOrientation(Qt::Vertical);
	m_splitterVertical->addWidget(m_splitter3DViews);
	m_splitterVertical->addWidget(m_splitter2DViews);

	QHBoxLayout *layout = new QHBoxLayout;
	layout->addWidget(m_splitterVertical);
	layout->setSpacing(0);
	layout->setMargin(0);
	setLayout(layout);


	connect(m_2dViewLeft, SIGNAL(emitMaxmizeMe(int)), SLOT(slotMaximizeView(int)));
	connect(m_2dViewLeft, SIGNAL(emitRestoreMe(int)), SLOT(slotRestoreView(int)));
	connect(m_2dViewLeft, SIGNAL(emitLeftClickedMe(int)), SLOT(slotActiveView(int)));
	connect(m_2dViewLeft, SIGNAL(emitSeedPicked()), SIGNAL(emitSeedPicked()));

	connect(m_2dViewRight, SIGNAL(emitMaxmizeMe(int)), SLOT(slotMaximizeView(int)));
	connect(m_2dViewRight, SIGNAL(emitRestoreMe(int)), SLOT(slotRestoreView(int)));
	connect(m_2dViewRight, SIGNAL(emitLeftClickedMe(int)), SLOT(slotActiveView(int)));
	connect(m_2dViewRight, SIGNAL(emitSeedPicked()), SIGNAL(emitSeedPicked()));

	connect(m_3dViewLeft, SIGNAL(emitMaxmizeMe(int)), SLOT(slotMaximizeView(int)));
	connect(m_3dViewLeft, SIGNAL(emitRestoreMe(int)), SLOT(slotRestoreView(int)));
	connect(m_3dViewLeft, SIGNAL(emitLeftClickedMe(int)), SLOT(slotActiveView(int)));
	connect(m_3dViewLeft, SIGNAL(emitStartCutting()), SIGNAL(emitStartCutting()));
	connect(m_3dViewLeft, SIGNAL(emitStopCutting()), SIGNAL(emitStopCutting()));
	connect(m_3dViewLeft, SIGNAL(emitDoCut()), SIGNAL(emitDoCut()));

	connect(m_3dViewRight, SIGNAL(emitMaxmizeMe(int)), SLOT(slotMaximizeView(int)));
	connect(m_3dViewRight, SIGNAL(emitRestoreMe(int)), SLOT(slotRestoreView(int)));
	connect(m_3dViewRight, SIGNAL(emitLeftClickedMe(int)), SLOT(slotActiveView(int)));
	connect(m_3dViewRight, SIGNAL(emitStartCutting()), SIGNAL(emitStartCutting()));
	connect(m_3dViewRight, SIGNAL(emitStopCutting()), SIGNAL(emitStopCutting()));
	connect(m_3dViewRight, SIGNAL(emitDoCut()), SIGNAL(emitDoCut()));
}


void DisplayFramework::resetLayout()
{
	QRect rect = frameRect();

	saveViewLayout();

	QList<int> size2Ds = m_splitterSizes2D;
	QList<int> size3Ds = m_splitterSizes3D;
	QList<int> sizeV  = m_splitterSizesVer;

	sizeV[0] = rect.height()/2 + 50;
	sizeV[1] = rect.height() - sizeV[0];

	size2Ds[0] = rect.width()/2;
	size2Ds[1] = rect.width() - size2Ds[0];

	size3Ds[0] = rect.width()/2;
	size3Ds[1] = rect.width() - size3Ds[0];

	m_splitter2DViews->setSizes(size2Ds);
	m_splitter3DViews->setSizes(size3Ds);
	m_splitterVertical->setSizes(sizeV);
}


void DisplayFramework::slotActiveView(int id)
{
	if ( id == 1)
	{
		m_2dViewLeft->setActivated(true);
		m_2dViewRight->setActivated(false);
	}
	else if ( id == 2)
	{
		m_2dViewLeft->setActivated(false);
		m_2dViewRight->setActivated(true);
	}
	else if ( id == 3)
	{
		m_3dViewLeft->setActivated(true);
		m_3dViewRight->setActivated(false);
	}
	else if ( id == 4)
	{
		m_3dViewLeft->setActivated(false);
		m_3dViewRight->setActivated(true);
	}

	m_pipeline->slotUpdate();
	emit emitViewActivated(id);
}


void DisplayFramework::initViews()
{
	

}


void DisplayFramework::slotMaximizeView(int id)
{
	if (m_isViewMaximized == true)
		return;

	saveViewLayout();

	QList<int> size2Ds = m_splitterSizes2D;
	QList<int> size3Ds = m_splitterSizes3D;
	QList<int> sizeV  = m_splitterSizesVer;

	int width = size2Ds[0] + size2Ds[1];
	int height = sizeV[0] + sizeV[1];

	size2Ds[0] = (id == 1) ? width:0;
	size2Ds[1] = (id == 2) ? width:0;

	size3Ds[0] = (id == 3) ? width:0;
	size3Ds[1] = (id == 4) ? width:0;

	sizeV[0] = (id == 1 || id == 2) ? 0 : height;
	sizeV[1] = (id == 3 || id == 4) ? 0 : height;

	m_splitter2DViews->setSizes(size2Ds);
	m_splitter3DViews->setSizes(size3Ds);
	m_splitterVertical->setSizes(sizeV);

	emit emitViewMaximized(id);
	m_isViewMaximized = true;
}


void DisplayFramework::slotRestoreView(int id)
{
	if (m_isViewMaximized == false)
		return;

	m_splitter2DViews->setSizes(m_splitterSizes2D);
	m_splitter3DViews->setSizes(m_splitterSizes3D);
	m_splitterVertical->setSizes(m_splitterSizesVer);

	m_isViewMaximized = false;
}


void DisplayFramework::saveViewLayout()
{
	m_splitterSizes2D = m_splitter2DViews->sizes();
	m_splitterSizes3D = m_splitter3DViews->sizes();
	m_splitterSizesVer = m_splitterVertical->sizes();
}


void DisplayFramework::setPipeline(PipelineModel *pipeline)
{
	this->m_pipeline = pipeline;

	//connect(m_pipeline, SIGNAL(emitSourceSelected(const QModelIndex&)), SLOT(slotSourceSelected(const QModelIndex&)));
	//connect(m_pipeline, SIGNAL(emitSourcePreRemove(const QModelIndex&)),SLOT(slotSourcePreRemove(const QModelIndex&)));
 	//connect(m_pipeline, SIGNAL(emitPropertyChanged(const QModelIndex&, SourceProperty)),SLOT(slotPropertyChanged(const QModelIndex&, SourceProperty)));
}


void DisplayFramework::slotSourceSelected(const QModelIndex& index)
{
	Source *source = (Source*)m_pipeline->itemFromIndex(index);
	if ( source == NULL)
		return;

// 	m_3dViewLeft->sourceSelected(source);
// 	m_3dViewRight->sourceSelected(source);
}


void DisplayFramework::slotSetBase(const QModelIndex& index)
{
// 	Source *source = (Source*)m_pipeline->itemFromIndex(index);
// 	if ( source == NULL || source == m_baseSource)
// 		return;
// 
// 	if ( source->getSourceType() == stVolume  && index.column() == 0 )
// 	{
// 		m_2dViewLeft->setBaseSource(source);
// 		//m_2dViewRight->setBaseSource(source, voCORONAL);
// 		//m_viewSagittal->setBaseSource(source, voSAGITTAL);
// 	}

//	m_baseSource = source;
}

void DisplayFramework::slotSourcePreRemove(const QModelIndex& index)
{
	if (!index.isValid())
		return;

	//Source *source = (Source*)m_pipeline->itemFromIndex(index);

}


void DisplayFramework::slotStartRealTimeSlicing(Source* source)
{
// 	m_isRealTimeSlicing = true;
// 
// 	m_realTimeSlicingView = getActive3DView();
// 	m_realTimeSlicingView->setRealTimeSlicing(source);
}


void DisplayFramework::slotStopRealTimeSlicing()
{
// 	m_isRealTimeSlicing = false;
// 
// 	if ( m_realTimeSlicingView)
// 		m_realTimeSlicingView->setRealTimeSlicing(NULL);
}


void DisplayFramework::slotUpdateSlicing()
{
// 	if ( !m_isRealTimeSlicing)
// 		return;
// 
// 	m_realTimeSlicingView->updateRealTimeSlicing();
}


View2D* DisplayFramework::getActive2DView()
{
	if ( m_2dViewLeft->isActivated())
		return m_2dViewLeft;
	else 
		return m_2dViewRight;

}


View3D* DisplayFramework::getActive3DView()
{
	if ( m_3dViewLeft->isActivated())
		return m_3dViewLeft;
	else
		return m_3dViewRight;
}

void DisplayFramework::slotLink3DViewCameras(bool flag)
{
	if ( flag)
	{
		m_3dViewRight->getRenderer()->SetActiveCamera(m_3dViewLeft->getRenderer()->GetActiveCamera());
		connect(m_3dViewLeft, SIGNAL(emitLinkedCameraMoving()), m_3dViewRight, SLOT(slotLinkedCameraMoving()));
		connect(m_3dViewRight, SIGNAL(emitLinkedCameraMoving()), m_3dViewLeft, SLOT(slotLinkedCameraMoving()));
		m_3dViewRight->cameraLinked(true);
		m_3dViewLeft->cameraLinked(true);
		m_3dViewLeft->setActivated(true);
		m_3dViewRight->setActivated(true);
	}
	else
	{
		m_3dViewRight->getRenderer()->SetActiveCamera(NULL);
		disconnect(m_3dViewLeft, SIGNAL(emitLinkedCameraMoving()), m_3dViewRight, SLOT(slotLinkedCameraMoving()));
		disconnect(m_3dViewRight, SIGNAL(emitLinkedCameraMoving()), m_3dViewLeft, SLOT(slotLinkedCameraMoving()));
		m_3dViewRight->cameraLinked(false);
		m_3dViewLeft->cameraLinked(false);
		m_3dViewRight->setActivated(false);
	}
}




